package com.ecarx.vhaltests.hy11.testcases.drivemode;


import static vendor.ecarx.xma.automotive.vehicle.V2_0.ECarXVehicleProperty.DRIVEMODE_PROJECTION_POSITION_SET;

import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.IpcpClient;
import com.ecarx.vhaltests.VehicleConstants;
import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import vendor.ecarx.xma.automotive.vehicle.V2_0.ECarXVehicleProperty;

//SW_FC_041_013 投影模式-投影位置调节
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class DriveModeProjectionPositionSetTest extends VhalUnitTestBase {

    private static final String TAG = "DRIVEMODE_PROJECTION_POSITION_SET";

    private static IpcpClient ipcpClient = new IpcpClient();
    
    private static final int AREA_ID = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;

    private static int[] halValue;
    private static int halStatus;
    final static Object lock = new Object();

    @BeforeClass
    public static void testInit() {
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, DRIVEMODE_PROJECTION_POSITION_SET, CarPropertyManager.SENSOR_RATE_ONCHANGE);
        setConfig();
    }

    @Test
    public void testProjectionPositionSetAvailable() {
        setProjectionPositionSetAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 0);
        testProjectionPositionSetAvai();
    }

    @Test
    public void testProjectionPositionSetNotAvailable() {
        setProjectionPositionSetNotAvailable();
        lockWait();
        Assert.assertEquals(halStatus, 1);
        testProjectionPositionSetNotAvai();
    }

   @Test
    public void testProjectionPositionSetUP() {
        setProScrenPosnUpDwnPosnAndProScrenPosnLeRiPosn(1, 2);  
        setProjectionPositionSetAvailable();
        delay();
        setProjectionPositionSetValue(1, 0);
        lockWait();
    }

    @Test
    public void testProjectionPositionSetLEFT() {
        setProScrenPosnUpDwnPosnAndProScrenPosnLeRiPosn(1, 3); 
        setProjectionPositionSetAvailable();
        delay();
        setProjectionPositionSetValue(3, 0);
        lockWait();
    }
    
    private void setProjectionPositionSetValue(int pos, int size){
        int[] value = new int[2]; 
        value[0] = pos;
        value[1] = size;      
        mCarPropertyMgr.setProperty(int[].class, DRIVEMODE_PROJECTION_POSITION_SET, AREA_ID, value);
    }

    private void setProjectionPositionSetAvailable(){
        setPrjtSwtFb(1);
    }

    private void setProjectionPositionSetNotAvailable(){
        setPrjtSwtFb(0);
    }

    private static void setConfig() {
        int ccSvcId = 135;
        int[] ccOperIds = {200};

        int cemSvcId = 37;
        int[] cemOperIds = {999};

        int vddmSvcId = 48;
        int[] vddmOperIds = {999};

        int fplSvcId = 67;
        int[] fplOperIds = {999};

        ipcpClient.setConfig(ccSvcId, ccOperIds);
        ipcpClient.setConfig(cemSvcId, cemOperIds);
        ipcpClient.setConfig(vddmSvcId, vddmOperIds);
        ipcpClient.setConfig(fplSvcId, fplOperIds);

        int[] configs = {745};
        int[] values = {0};
        boolean ccRet = ipcpClient.setCarconfigSignal(ccSvcId, ccOperIds[0], configs, values);
        Assert.assertTrue(ccRet);

    }

    private void setPrjtSwtFb(int value){
        int fplSvcId = 67;
        int[] fplOperIds = {999};

        String[] fpls = {"prjtSwtFb"};
        int[] fplValues = {value};
        boolean fplsRet = ipcpClient.setFPLSignal(fplSvcId, fplOperIds[0], fpls, fplValues);
        Assert.assertTrue(fplsRet);
    }

    private void setProScrenPosnUpDwnPosnAndProScrenPosnLeRiPosn(int value, int value2){
        int fplSvcId = 67;
        int[] fplOperIds = {999};

        String[] fpls = {"proScrenPosnUpDwnPosn", "proScrenPosnLeRiPosn"};
        int[] fplValues = {value, value2};
        boolean fplsRet = ipcpClient.setFPLSignal(fplSvcId, fplOperIds[0], fpls, fplValues);
        Assert.assertTrue(fplsRet);
    }
    
    private void testProjectionPositionSetAvai(){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(DRIVEMODE_PROJECTION_POSITION_SET, AREA_ID);
        Assert.assertTrue(isAvail);
    }

    private void testProjectionPositionSetNotAvai(){
        boolean isAvail = mCarPropertyMgr.isPropertyAvailable(DRIVEMODE_PROJECTION_POSITION_SET, AREA_ID);
        Assert.assertFalse(isAvail);
    }

    private static final CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
        @Override
        public void onChangeEvent(CarPropertyValue carPropertyValue) {
            try {
                Log.d(TAG, carPropertyValue.toString());
                halValue = (int[])carPropertyValue.getValue();
                halStatus = carPropertyValue.getStatus();
                synchronized (lock) {
                    lock.notify();
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }

        @Override
        public void onErrorEvent(int i, int i1) {
        }
    };

    public void lockWait() {
        try {
            synchronized (lock) {
                lock.wait(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
